<?php

/**
 * Loobica user location library
 * 
 * @author  Dino (DBK)
 * @date    22 Jan 2014
 * 
 */
if (!defined('BASEPATH'))
  exit('No direct script access allowed');

class User_location {

  var $ci;
  var $loc_data = null;

  /**
   * Getting CI Instance
   * 
   */
  public function __construct() {
    $this->ci = & get_instance();
  }

  /**
   * Setting location cookie data
   * 
   * @param type $loc_key
   * @return type
   */
  private function set_data($loc_key = array()) {
    return set_cookie('loobica_location', (string) $loc_key, time() + (20 * 365 * 24 * 60 * 60));
  }

  /**
   * Getting location cookie data
   * 
   * @return type
   */
  private function get_data() {
    return (string) get_cookie('loobica_location', true);
  }

  /**
   * Set location
   * 
   * @param type $loc_key
   * @return type
   */
  public function set($loc_key = null) {

    // Checking location key
    if (!empty($loc_key)) {

      // Spliting key
      $id_split = explode('@', $loc_key);

      // Checking valid key
      if (!empty($id_split[0]) && !empty($id_split[1])) {

        // Setting extracted key datas
        $loc_id = (int) $id_split[0];
        $loc_level = (int) $id_split[1];

        // Getting loction data
        $loc_data = array();
        if ($loc_level == 1) {
          $loc_data = $this->ci->location_model->get_country_id($loc_id);
        }
        if ($loc_level == 2) {
          $loc_data = $this->ci->location_model->get_state_id($loc_id);
        }
        if ($loc_level == 3) {
          $loc_data = $this->ci->location_model->get_district_id($loc_id);
        }
        if ($loc_level == 4) {
          $loc_data = $this->ci->location_model->get_locality_id($loc_id);
        }

        // Checking location data
        if (!empty($loc_data)) {
          return $this->set_data($loc_key);
        }
      }
    }

    return false;
  }

  /**
   * Get location
   * 
   * @return null
   */
  public function get() {

    // Getting cookie data
    $cookie_data = $this->get_data();

    // Making loc data
    if (!empty($cookie_data)) {
      $loc_key = (string) $cookie_data;
    } elseif (!empty($this->ci->signed_user)) {
      $loc_key = (string) $this->ci->signed_user['user_location_key'];
    } else {
      $loc_key = null;
    }

    // Getting data from loc key
    return $this->get_key_data($loc_key);
  }

  /**
   * Make Location Data from Location Key
   * 
   * @param type $loc_key
   * @return type
   */
  public function get_key_data($loc_key = null) {

    // Checking location key
    if (!empty($loc_key)) {

      // Spliting key
      $id_split = explode('@', $loc_key);

      // Checking valid key
      if (!empty($id_split[0]) && !empty($id_split[1])) {

        // Setting extracted key datas
        $loc_id = (int) $id_split[0];
        $loc_level = (int) $id_split[1];

        // Getting location data according to level
        if ($loc_level == 1) {
          $loc_data = $this->ci->location_model->get_country_id($loc_id);
        } elseif ($loc_level == 2) {
          $loc_data = $this->ci->location_model->get_country_state_id($loc_id);
        } elseif ($loc_level == 3) {
          $loc_data = $this->ci->location_model->get_country_state_district_id($loc_id);
        } elseif ($loc_level == 4) {
          $loc_data = $this->ci->location_model->get_country_state_district_locality_id($loc_id);
        } else {
          $loc_data = array();
        }

        // Cheking location data exists
        if (!empty($loc_data)) {
          $id = array('id' => $loc_id);
          $level = array('level' => $loc_level);
          return array_merge($id, $level, $loc_data);
        }
      }
    }

    return array();
  }

  /**
   * Get Location From Name
   * 
   * @param type $loc_value
   * @return type
   */
  public function get_location($loc_value = 0) {

    $loc_key = null;

    // Get google zip data
    $loc_data = $this->make_location($loc_value);

    if (!empty($loc_data)) {

      // Check and insert country
      $country_id = 0;
      if (!empty($loc_data['country'])) {
        $country_data = $this->ci->location_model->get_country($loc_data['country']);
        if (!empty($country_data)) {
          $country_id = $country_data['country_id'];
        } else {
          if (!is_numeric($loc_data['country'])) {
            $country_id = $this->ci->location_model->put_country($loc_data['country']);
          }
        }
      }

      // Set loc key level 1
      if (!empty($country_id)) {
        $loc_key = $country_id . '@' . 1;
      }

      // Check and insert state
      $state_id = 0;
      if (!empty($loc_data['state'])) {
        $state_data = $this->ci->location_model->get_state($loc_data['state']);
        if (!empty($state_data)) {
          $state_id = $state_data['state_id'];
        } else {
          if (!empty($country_id) && !is_numeric($loc_data['state'])) {
            $state_id = $this->ci->location_model->put_state($loc_data['state'], $country_id);
          }
        }
      }

      // Set loc key level 2
      if (!empty($state_id)) {
        $loc_key = $state_id . '@' . 2;
      }

      // Check and insert district
      $district_id = 0;
      if (!empty($loc_data['district'])) {
        $district_data = $this->ci->location_model->get_district($loc_data['district']);
        if (!empty($district_data)) {
          $district_id = $district_data['district_id'];
        } else {
          if (!empty($state_id) && !is_numeric($loc_data['district'])) {
            $district_id = $this->ci->location_model->put_district($loc_data['district'], $state_id);
          }
        }
      }

      // Set loc key level 3
      if (!empty($district_id)) {
        $loc_key = $district_id . '@' . 3;
      }

      // Check and insert locality
      $locality_id = 0;
      if (!empty($loc_data['locality'])) {
        $locality_data = $this->ci->location_model->get_locality($loc_data['locality']);
        if (!empty($locality_data)) {
          $locality_id = $locality_data['locality_id'];
        } else {
          if (!empty($district_id) && !is_numeric($loc_data['locality'])) {
            $locality_id = $this->ci->location_model->put_locality($loc_data['locality'], $district_id);
          }
        }
      }

      // Set loc key level 4
      if (!empty($locality_id)) {
        $loc_key = $locality_id . '@' . 4;
      }


      // Return data
      if (!empty($loc_key)) {
        return $this->loc_data = array(
            'loc_key' => $loc_key,
            'country_id' => $country_id,
            'country_name' => $loc_data['country'],
            'state_id' => $state_id,
            'state_name' => $loc_data['state'],
            'district_id' => $district_id,
            'district_name' => $loc_data['district'],
            'locality_id' => $locality_id,
            'locality_name' => $loc_data['locality']
        );
      }
    }

    return array();
  }

  /**
   * Returns location data genrerated
   * 
   * @return type
   */
  public function data() {
    return $this->loc_data;
  }

  /**
   * Location Data from Google API
   * 
   * @param type $value
   * @return type
   */
  private function make_location($value = null) {
    $result = array('country' => null, 'state' => null, 'district' => null, 'locality' => null);
    if (!empty($value)) {
      $loc_data = file_get_contents("http://maps.googleapis.com/maps/api/geocode/json?address=" . urlencode($value) . "&sensor=true");
      if (!empty($loc_data)) {
        $loc_array = json_decode($loc_data, true);
        if (!empty($loc_array['results'][0]['address_components'])) {
          foreach ($loc_array['results'][0]['address_components'] as $address) {
            if ($address['types'][0] == 'country') {
              $result['country'] = $address['long_name'];
            }
            if ($address['types'][0] == 'administrative_area_level_1') {
              $result['state'] = $address['long_name'];
            }
            if ($address['types'][0] == 'administrative_area_level_2') {
              $result['district'] = $address['long_name'];
            }
            if ($address['types'][0] == 'locality') {
              $result['locality'] = $address['long_name'];
            }
          }
        }
      }
    }
    return $result;
  }

}
